"""
Case Type   : resource pool
Case Name   : 修改业务资源池的控制组为Timeshar控制组，部分测试点合理报错
Create At   : 2022/08/29
Owner       : songjing20
Description :
    1.预置子class控制组及Workload控制组
    2.创建组、业务资源池
    3.修改控制组为当前所在子class控制组下的Low/High Timeshare控制组
    4.修改控制组为class_b下的 Medium Timeshar控制组,class_b未被关联
    5.修改控制组为class_b下的 High Timeshar控制组,class_b已被关联
    6.修改控制组为默认子class控制组下的 Rush Timeshar控制组
    7.环境清理
Expect      :
    1.创建成功
    2.创建成功
    3.修改成功
    4.合理报错
    5.合理报错
    6.报错
    7.清理成功
History     :
"""
import os
import unittest

from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant


class ResourcePool(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f"-----{os.path.basename(__file__)} start-----")
        self.pri_node = Node('PrimaryDbUser')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.constant = Constant()
        self.class_a = 'class_a'
        self.class_b = 'class_b'
        self.group_a1 = 'workload_a1'
        self.group_a2 = 'workload_a2'
        self.group_a3 = 'workload_a3'
        self.respool = [f'resp_resource_pool_0059_{i}' for i in range(1, 6)]

    def test_resource_pool(self):
        text = "-----step1:预置子class控制组及Workload控制组;expect:创建成功-----"
        self.log.info(text)
        cmd = f"source {macro.DB_ENV_PATH};" \
              f"gs_cgroup -c -S {self.class_a} -s 20; " \
              f"gs_cgroup -c -S {self.class_a} -G {self.group_a1} -g 20; " \
              f"gs_cgroup -c -S {self.class_a} -G {self.group_a2} -g 10; " \
              f"gs_cgroup -c -S {self.class_a} -G {self.group_a3} -g 40; " \
              f"gs_cgroup -c -S {self.class_b} -s 10; " \
              f"gs_cgroup -p"
        self.log.info(cmd)
        cmd_res = self.pri_node.sh(cmd).result()
        self.log.info(cmd_res)
        self.assertIn(f"CLASS  Name: {self.class_a}", cmd_res,
                      f'执行失败:{text}')
        self.assertIn(f"CLASS  Name: {self.class_b}", cmd_res,
                      f'执行失败:{text}')
        self.assertIn(f"DEFWD  Name: {self.group_a1}", cmd_res,
                      f'执行失败:{text}')
        self.assertIn(f"DEFWD  Name: {self.group_a2}", cmd_res,
                      f'执行失败:{text}')
        self.assertIn(f"DEFWD  Name: {self.group_a3}", cmd_res,
                      f'执行失败:{text}')

        text = "-----step2:创建组、业务资源池;expect:创建成功-----"
        self.log.info(text)
        sql = f'''create resource pool {self.respool[0]}
        with(control_group = '{self.class_a}');
        create resource pool {self.respool[1]}
        with(control_group = '{self.class_a}:{self.group_a1}');
        create resource pool {self.respool[2]}
        with(control_group = '{self.class_a}:{self.group_a2}');
        create resource pool {self.respool[3]}
        with(control_group = '{self.class_a}:{self.group_a3}');
        select pg_sleep(3);
        select respool_name, control_group from pg_resource_pool
        where respool_name like '{self.respool[0][:-2]}%' order by 1;'''
        sql_res = self.pri_sh.execut_db_sql(sql)
        self.log.info(sql_res)
        self.assertEqual(4, sql_res.count(
            self.constant.create_resource_pool_success), f'执行失败:{text}')
        self.assertIn(f'{self.respool[0]} | {self.class_a}\n '
                      f'{self.respool[1]} | {self.class_a}:{self.group_a1}\n '
                      f'{self.respool[2]} | {self.class_a}:{self.group_a2}\n '
                      f'{self.respool[3]} | {self.class_a}:{self.group_a3}',
                      sql_res, f'执行失败:{text}')

        text = "-----step3:修改控制组为当前所在子class控制组下的" \
               "Low/High Timeshare控制组;expect:修改成功-----"
        self.log.info(text)
        sql_res = self.pri_sh.execut_db_sql(
            f"alter resource pool {self.respool[1]} "
            f"with(control_group = '{self.class_a}:Low');"
            f"alter resource pool {self.respool[2]} "
            f"with(control_group = '{self.class_a}:High');"
            f"select pg_sleep(3);"
            f"select respool_name, control_group from pg_resource_pool "
            f"where respool_name in('{self.respool[1]}','{self.respool[2]}') "
            f"order by 1;")
        self.log.info(sql_res)
        self.assertEqual(2, sql_res.count(
            self.constant.alter_resource_pool_success), f'执行失败:{text}')
        self.assertIn(f'{self.respool[1]} | {self.class_a}:Low\n '
                      f'{self.respool[2]} | {self.class_a}:High',
                      sql_res, f'执行失败:{text}')

        text = "-----step4:修改控制组为class_b下的 Medium Timeshar控制组,class_b未被关联;" \
               "expect:合理报错-----"
        self.log.info(text)
        sql_res = self.pri_sh.execut_db_sql(
            f"alter resource pool {self.respool[3]} "
            f"with(control_group = '{self.class_b}:Medium');"
            f"select respool_name, control_group from pg_resource_pool "
            f"where respool_name = '{self.respool[3]}';")
        self.log.info(sql_res)
        flag = 'ERROR:  cannot alter control_group between different groups' \
               ' or alter to a different layer'
        self.assertIn(flag, sql_res, f'执行失败:{text}')
        self.assertIn(f'{self.respool[3]} | {self.class_a}:{self.group_a3}',
                      sql_res, f'执行失败:{text}')

        text = "-----step5:修改控制组为class_b下的 High Timeshar控制组,class_b已被关联;" \
               "expect:修改失败-----"
        self.log.info(text)
        sql_res = self.pri_sh.execut_db_sql(
            f"create resource pool {self.respool[4]} "
            f"with (control_group = '{self.class_b}');"
            f"alter resource pool {self.respool[3]} "
            f"with(control_group = '{self.class_b}:High');"
            f"select respool_name, control_group from pg_resource_pool "
            f"where respool_name = '{self.respool[3]}';")
        self.log.info(sql_res)
        self.assertIn(self.constant.create_resource_pool_success, sql_res,
                      f'执行失败:{text}')
        self.assertIn(flag, sql_res, f'执行失败:{text}')
        self.assertIn(f'{self.respool[3]} | {self.class_a}:{self.group_a3}',
                      sql_res, f'执行失败:{text}')

        text = "-----step6:修改控制组为默认子class控制组下的 Rush Timeshar控制组;" \
               "expect:报错-----"
        self.log.info(text)
        sql_res = self.pri_sh.execut_db_sql(
            f"alter resource pool {self.respool[3]} "
            f"with(control_group = 'Rush');"
            f"alter resource pool {self.respool[3]} "
            f"with(control_group = 'DefaultClass:Rush');"
            f"select respool_name, control_group from pg_resource_pool "
            f"where respool_name = '{self.respool[3]}';")
        self.log.info(sql_res)
        self.assertEqual(sql_res.count(flag), 2, f'执行失败:{text}')
        self.assertIn(f'{self.respool[3]} | {self.class_a}:{self.group_a3}',
                      sql_res, f'执行失败:{text}')

    def tearDown(self):
        text = "-----step7:环境清理;expect:成功-----"
        self.log.info(text)
        drop_res = self.pri_sh.execut_db_sql(
            ';\n'.join(
                [f"drop resource pool if exists {i}" for i in self.respool]))
        self.log.info(drop_res)
        cmd = f"source {macro.DB_ENV_PATH};gs_cgroup --revert"
        self.log.info(cmd)
        cmd_res = self.pri_node.sh(cmd).result()
        self.assertEqual(5, drop_res.count(
            self.constant.drop_resource_pool_success), f'执行失败:{text}')
        self.assertEqual('', cmd_res, f'执行失败:{text}')
        self.log.info(f"-----{os.path.basename(__file__)} end-----")
